home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / ViePratique / ArchiFacile / ArchiFacileSetup.exe / {app} / nw.pak / Unnamed File 000114.txt < prev    next >
Text File  |  2014-10-14  |  9KB  |  274 lines

  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4.  
  5. cr.define('cr.ui', function() {
  6.   /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
  7.   /** @const */ var List = cr.ui.List;
  8.   /** @const */ var ListItem = cr.ui.ListItem;
  9.  
  10.   /**
  11.    * Creates a new autocomplete list item.
  12.    * This is suitable for selecting a web site, and used by default.
  13.    * A different behavior can be set by AutocompleteListItem.itemConstructor.
  14.    * @param {Object} pageInfo The page this item represents.
  15.    * @constructor
  16.    * @extends {cr.ui.ListItem}
  17.    */
  18.   function AutocompleteListItem(pageInfo) {
  19.     var el = cr.doc.createElement('div');
  20.     el.pageInfo_ = pageInfo;
  21.     AutocompleteListItem.decorate(el);
  22.     return el;
  23.   }
  24.  
  25.   /**
  26.    * Decorates an element as an autocomplete list item.
  27.    * @param {!HTMLElement} el The element to decorate.
  28.    */
  29.   AutocompleteListItem.decorate = function(el) {
  30.     el.__proto__ = AutocompleteListItem.prototype;
  31.     el.decorate();
  32.   };
  33.  
  34.   AutocompleteListItem.prototype = {
  35.     __proto__: ListItem.prototype,
  36.  
  37.     /** @override */
  38.     decorate: function() {
  39.       ListItem.prototype.decorate.call(this);
  40.  
  41.       var title = this.pageInfo_['title'];
  42.       var url = this.pageInfo_['displayURL'];
  43.       var titleEl = this.ownerDocument.createElement('span');
  44.       titleEl.className = 'title';
  45.       titleEl.textContent = title || url;
  46.       this.appendChild(titleEl);
  47.  
  48.       if (title && title.length > 0 && url != title) {
  49.         var separatorEl = this.ownerDocument.createTextNode(' - ');
  50.         this.appendChild(separatorEl);
  51.  
  52.         var urlEl = this.ownerDocument.createElement('span');
  53.         urlEl.className = 'url';
  54.         urlEl.textContent = url;
  55.         this.appendChild(urlEl);
  56.       }
  57.     },
  58.   };
  59.  
  60.   /**
  61.    * Creates a new autocomplete list popup.
  62.    * @constructor
  63.    * @extends {cr.ui.List}
  64.    */
  65.   var AutocompleteList = cr.ui.define('list');
  66.  
  67.   AutocompleteList.prototype = {
  68.     __proto__: List.prototype,
  69.  
  70.     /**
  71.      * The text field the autocomplete popup is currently attached to, if any.
  72.      * @type {HTMLElement}
  73.      * @private
  74.      */
  75.     targetInput_: null,
  76.  
  77.     /**
  78.      * Keydown event listener to attach to a text field.
  79.      * @type {Function}
  80.      * @private
  81.      */
  82.     textFieldKeyHandler_: null,
  83.  
  84.     /**
  85.      * Input event listener to attach to a text field.
  86.      * @type {Function}
  87.      * @private
  88.      */
  89.     textFieldInputHandler_: null,
  90.  
  91.     /** @override */
  92.     decorate: function() {
  93.       List.prototype.decorate.call(this);
  94.       this.classList.add('autocomplete-suggestions');
  95.       this.selectionModel = new cr.ui.ListSingleSelectionModel;
  96.  
  97.       this.itemConstructor = AutocompleteListItem;
  98.       this.textFieldKeyHandler_ = this.handleAutocompleteKeydown_.bind(this);
  99.       var self = this;
  100.       this.textFieldInputHandler_ = function(e) {
  101.         self.requestSuggestions(self.targetInput_.value);
  102.       };
  103.       this.addEventListener('change', function(e) {
  104.         if (self.selectedItem)
  105.           self.handleSelectedSuggestion(self.selectedItem);
  106.       });
  107.       // Start hidden; adding suggestions will unhide.
  108.       this.hidden = true;
  109.     },
  110.  
  111.     /** @override */
  112.     createItem: function(pageInfo) {
  113.       return new this.itemConstructor(pageInfo);
  114.     },
  115.  
  116.     /**
  117.      * The suggestions to show.
  118.      * @type {Array}
  119.      */
  120.     set suggestions(suggestions) {
  121.       this.dataModel = new ArrayDataModel(suggestions);
  122.       this.hidden = !this.targetInput_ || suggestions.length == 0;
  123.     },
  124.  
  125.     /**
  126.      * Requests new suggestions. Called when new suggestions are needed.
  127.      * @param {string} query the text to autocomplete from.
  128.      */
  129.     requestSuggestions: function(query) {
  130.     },
  131.  
  132.     /**
  133.      * Handles the Enter keydown event.
  134.      * By default, clears and hides the autocomplete popup. Note that the
  135.      * keydown event bubbles up, so the input field can handle the event.
  136.      */
  137.     handleEnterKeydown: function() {
  138.       this.suggestions = [];
  139.     },
  140.  
  141.     /**
  142.      * Handles the selected suggestion. Called when a suggestion is selected.
  143.      * By default, sets the target input element's value to the 'url' field
  144.      * of the selected suggestion.
  145.      * @param {Event} event The change event.
  146.      */
  147.     handleSelectedSuggestion : function(selectedSuggestion) {
  148.       var input = this.targetInput_;
  149.       if (!input)
  150.         return;
  151.       input.value = selectedSuggestion['url'];
  152.       // Programatically change the value won't trigger a change event, but
  153.       // clients are likely to want to know when changes happen, so fire one.
  154.       cr.dispatchSimpleEvent(input, 'change', true);
  155.     },
  156.  
  157.     /**
  158.      * Attaches the popup to the given input element. Requires
  159.      * that the input be wrapped in a block-level container of the same width.
  160.      * @param {HTMLElement} input The input element to attach to.
  161.      */
  162.     attachToInput: function(input) {
  163.       if (this.targetInput_ == input)
  164.         return;
  165.  
  166.       this.detach();
  167.       this.targetInput_ = input;
  168.       this.style.width = input.getBoundingClientRect().width + 'px';
  169.       this.hidden = false;  // Necessary for positionPopupAroundElement to work.
  170.       cr.ui.positionPopupAroundElement(input, this, cr.ui.AnchorType.BELOW);
  171.       // Start hidden; when the data model gets results the list will show.
  172.       this.hidden = true;
  173.  
  174.       input.addEventListener('keydown', this.textFieldKeyHandler_, true);
  175.       input.addEventListener('input', this.textFieldInputHandler_);
  176.  
  177.       if (!this.boundSyncWidthAndPositionToInput_) {
  178.         this.boundSyncWidthAndPositionToInput_ =
  179.             this.syncWidthAndPositionToInput.bind(this);
  180.       }
  181.       // We need to call syncWidthAndPositionToInput whenever page zoom level or
  182.       // page size is changed.
  183.       window.addEventListener('resize', this.boundSyncWidthAndPositionToInput_);
  184.     },
  185.  
  186.     /**
  187.      * Detaches the autocomplete popup from its current input element, if any.
  188.      */
  189.     detach: function() {
  190.       var input = this.targetInput_;
  191.       if (!input)
  192.         return;
  193.  
  194.       input.removeEventListener('keydown', this.textFieldKeyHandler_, true);
  195.       input.removeEventListener('input', this.textFieldInputHandler_);
  196.       this.targetInput_ = null;
  197.       this.suggestions = [];
  198.       if (this.boundSyncWidthAndPositionToInput_) {
  199.         window.removeEventListener(
  200.             'resize', this.boundSyncWidthAndPositionToInput_);
  201.       }
  202.     },
  203.  
  204.     /**
  205.      * Makes sure that the suggestion list matches the width and the position
  206.      * of the input it is attached to. Should be called any time the input is
  207.      * resized.
  208.      */
  209.     syncWidthAndPositionToInput: function() {
  210.       var input = this.targetInput_;
  211.       if (input) {
  212.         this.style.width = input.getBoundingClientRect().width + 'px';
  213.         cr.ui.positionPopupAroundElement(input, this, cr.ui.AnchorType.BELOW);
  214.       }
  215.     },
  216.  
  217.     /**
  218.      * syncWidthAndPositionToInput function bound to |this|.
  219.      * @type {Function}
  220.      * @private
  221.      */
  222.     boundSyncWidthAndPositionToInput_: undefined,
  223.  
  224.     /**
  225.      * @return {HTMLElement} The text field the autocomplete popup is currently
  226.      *     attached to, if any.
  227.      */
  228.     get targetInput() {
  229.       return this.targetInput_;
  230.     },
  231.  
  232.     /**
  233.      * Handles input field key events that should be interpreted as autocomplete
  234.      * commands.
  235.      * @param {Event} event The keydown event.
  236.      * @private
  237.      */
  238.     handleAutocompleteKeydown_: function(event) {
  239.       if (this.hidden)
  240.         return;
  241.       var handled = false;
  242.       switch (event.keyIdentifier) {
  243.         case 'U+001B':  // Esc
  244.           this.suggestions = [];
  245.           handled = true;
  246.           break;
  247.         case 'Enter':
  248.           // If the user has already selected an item using the arrow keys then
  249.           // presses Enter, keep |handled| = false, so the input field can
  250.           // handle the event as well.
  251.           this.handleEnterKeydown();
  252.           break;
  253.         case 'Up':
  254.         case 'Down':
  255.           var newEvent = new Event(event.type);
  256.           newEvent.keyIdentifier = event.keyIdentifier;
  257.           this.dispatchEvent(newEvent);
  258.           handled = true;
  259.           break;
  260.       }
  261.       // Don't let arrow keys affect the text field, or bubble up to, e.g.,
  262.       // an enclosing list item.
  263.       if (handled) {
  264.         event.preventDefault();
  265.         event.stopPropagation();
  266.       }
  267.     },
  268.   };
  269.  
  270.   return {
  271.     AutocompleteList: AutocompleteList
  272.   };
  273. });
  274.